package com.tars.txtc.netty;

import com.alibaba.fastjson.JSONObject;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: Franz 2022/3/19
 */
public class NettyServerHandler extends SimpleChannelInboundHandler<String> {

    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    //各个事务分组的事务状态
    private static Map<String, List<Integer>> groupStatus = new ConcurrentHashMap<String, List<Integer>>();

    //事务是否结束
    private static Map<String, Boolean> txIsEnd = new ConcurrentHashMap<String, Boolean>();


    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.add(channel);
    }

    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        //1.获取事务信息
        System.out.println("事务管理中心: " + msg);
        JSONObject json = JSONObject.parseObject(msg);
        String txGroupID = json.get("txGroupID").toString();
        Integer status = Integer.valueOf(json.get("status").toString());
        Boolean isEnd = Boolean.valueOf(json.get("isEnd").toString());
        Integer txCount = Integer.valueOf(json.get("txCount").toString());

        //2.注册事务信息到容器
        if (groupStatus.containsKey(txGroupID)) {
            groupStatus.get(txGroupID).add(status);
        } else {
            ArrayList list = new ArrayList();
            list.add(status);
            groupStatus.put(txGroupID, list);
        }

        //3.判断事务是否结束
        if (isEnd) {
            txIsEnd.put(txGroupID,isEnd);
        }

        //4.判断是否需要通知所有事务
        if(txIsEnd.get(txGroupID)!=null
                && txIsEnd.get(txGroupID)
                && groupStatus.get(txGroupID).size()== txCount){
            JSONObject result = new JSONObject();
            if(groupStatus.get(txGroupID).contains(0)){
                System.out.println("事务分组:"+txGroupID+",执行失败");
                result.put("groupId",txGroupID);
                result.put("status",0);
            }else {
                System.out.println("事务分组:"+txGroupID+",执行成功");
                result.put("groupId",txGroupID);
                result.put("status",1);
            }
            sendGlobalResutl(result);
        }
    }

    private void sendGlobalResutl(JSONObject result) {
        for (Channel channel : channelGroup) {
            System.out.println("发送数据：" + result.toJSONString());
            channel.writeAndFlush(result.toJSONString());
        }
    }
}
